#ifndef LISTVIEW_H
#define LISTVIEW_H

#include <boost/signals2.hpp>
#include <string>
#include "view.h"
#include "scrollbar.h"
#include "rowlabel.h"
class Font;
class App;

class ListView : public View {
public:
     static const int NoIndex = -1;
     static const int NoCol = -1;
     // onChange signal template
     typedef boost::signals2::signal<void (int)> OnChange;
     typedef boost::signals2::signal<void (const std::string&)> OnNameChange;

     ListView(Rect r, App *pApp);
     int count() const;
     const std::string& itemAt(int i) const;
     void removeItemAt(int i);
     void setItemAt(int i, const std::string &str);
     void addItem(const std::string &str);
     int curIndex() const;
     void setCurIndex(int i);
     void incCurIndex();
     void decCurIndex();
     void setRect(Rect r);
     void paint(bool all);
     void updateOffset(int offset);
     void mouseDown(Point p, int button);
     void keyDown(int keycode, int modifiers, int unichar);
     // connect to onChange signal
     boost::signals2::connection onChange(const OnChange::slot_type &callback);
     boost::signals2::connection onNameChange(const OnNameChange::slot_type &callback);
     void clearList();
     void blur();

private:
     static const int Padding = 2;
     static const int LineThick = 1;
     App *m_pApp;
     RowLabel m_rowLabel;
     int m_offset;
     int m_curIndex;
     int m_curCol;
     ScrollBar m_scrollBar;
     std::vector<std::string> m_items;
     Rect m_listRect;
     boost::signals2::connection m_scrollConn;
     // signal to emit when current index changes
     OnChange m_onChange;
     OnNameChange m_onNameChange;
     bool m_editing;
     int m_editIndex;

     void paintList();
     int wholeVisibleRows();
     int visibleRows();
     void setOffset(int offset);
     bool setIndexAtPoint(Point p);
     void editName();
     int nameLength();
     void updateCount();
     void editDone();
};

#endif
